#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>

#define STOP  0
#define PAUSE 1
#define CONTI 2
#define PLAY 3
#define WEB 4
#define FM 5
#define COM_NUM 7
#define NC  (COM_NUM-1)

static struct class *player_class;
static struct device *player_device;

static int id=0;
static int fm_id=5;
static int com=NC;
static char com_id_w=0;
static char com_id_r=0;
static char url[100];

static int player_open(struct inode *inode, struct file *file) {
	//url = kmalloc(100,sizeof(char));
	return 0;
}

#define COMMAND 0
#define ID 1
#define URL 2
#define RADIO 3
#define WRITE_ID 255
#define READ_ID 254
#define WRITE_URL 245
#define READ_URL 244
#define WRITE_FM 235
#define READ_FM 234
long player_ioctl(struct file *file, unsigned int com_id, unsigned long data){
	switch(com_id){
		case READ_ID:com_id_r = ID;break;
		case WRITE_ID:com_id_w = ID;break;
		case READ_URL:com_id_r = URL;break;
		case WRITE_URL:com_id_w = URL;break;
		case READ_FM:com_id_r = RADIO;break;
		case WRITE_FM:com_id_w = RADIO;break;
	}
	return 0;
}

ssize_t player_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
{
	if(com_id_w == COMMAND){
		copy_from_user(&com,buf,4);
		printk("mod_write:id = %d\n", id);
	}else if(com_id_w == ID){
		copy_from_user(&id,buf,4);
		com = PLAY;
		printk("mod_write:id = %d\n", id);
		com_id_w = COMMAND;
	}else if(com_id_w == URL){
		copy_from_user(&url,buf,count);
		com = WEB;
		printk("mod_write:id = %d\n", id);
		com_id_w = COMMAND;
	}
	else if(com_id_w == RADIO){
		copy_from_user(&fm_id,buf,4);
		com = FM;
		printk("mod_write:id = %d\n", id);
		com_id_w = COMMAND;
	}
	return 0;
}


ssize_t player_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
	if(com_id_r == COMMAND){
	  copy_to_user(buf,&com,4);
	  printk("mod_write:com = %d\n", com);
	}
	else if(com_id_r == ID){
	 copy_to_user(buf, &id, 4);
	 printk("mod_write:id = %d\n", id);
	 com_id_r = COMMAND;
	}
	else if(com_id_r == URL){
	 copy_to_user(buf, &url, sizeof(url));
	 printk("mod_write:id = %d\n", id);
	 com_id_r = COMMAND;
	}
	else if(com_id_r == RADIO){
	 copy_to_user(buf, &fm_id, 4);
	 printk("mod_write:id = %d\n", id);
	 com_id_r = COMMAND;
	}
	return sizeof(id);
}

static struct file_operations player_fops={
	.owner = THIS_MODULE,
	.read = player_read,
	.write = player_write,
	.unlocked_ioctl = player_ioctl,
	.open = player_open,
};

int major;
static int player_init(void){
	major = register_chrdev(0,"player_dev",&player_fops);
	player_class = class_create(THIS_MODULE, "player_dev");
	player_device = device_create(player_class, NULL, MKDEV(major, 0), NULL, "MX");
	return 0;
}

static void player_exit(void){
	unregister_chrdev(major, "player_dev");
	device_unregister(player_device);
	id = 0;
	class_destroy(player_class);
}

module_init(player_init);
module_exit(player_exit);

MODULE_LICENSE("GPL");
